package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmAddDataService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.help.DynamicHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.parent.pojo.AddValidateReturnPojo;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.pro.formdata.pojo.vo.SaveVO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.saas.domain.entity.competitor.CompetitorEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.CompetitorModel;
import com.xbongbong.saas.service.CompetitorService;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: yingjf
 * @date: 2022/8/18 10:14
 * @description: 竞争对手
 */
@Slf4j
@Service("competitorFormDataService")
public class CompetitorFormDataServiceImpl extends AbstractCrmAddDataService {
    @Resource
    private CompetitorModel competitorModel;
    @Resource
    private CompetitorService competitorService;
    @Resource
    private DynamicHelp dynamicHelp;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private UserModel userModel;

    @Override
    public void apiHook(FormDataAddDTO formDataAddDTO, SaveVO saveVO, BeforeSaveVO beforeSaveVO) throws XbbException {

    }

    @Override
    public AddValidateReturnPojo analyticalData(FormDataAddDTO formDataAddDTO, ValidateDataDTO validateDataDTO, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        AddValidateReturnPojo addValidateReturnPojo = super.analyticalData(formDataAddDTO, validateDataDTO, explainMap);
        formDataAddDTO.setVisbleDept(validateDataDTO.getVisbleDept());
        formDataAddDTO.setVisbleUser(validateDataDTO.getVisbleUser());
        return addValidateReturnPojo;
    }

    @Override
    public List<Integer> businessList() {
        return Arrays.asList(XbbRefTypeEnum.COMPETITOR.getCode());
    }

    @Override
    public SaveVO save(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            UserVO userVO = getUserName(formDataAddDTO, paasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();
            if (Objects.equals(1, noApprovalRequired)) {
                CompetitorEntity competitorEntity = new CompetitorEntity();
                BeanUtil.copyProperties(paasFormDataEntity, competitorEntity);
                FormDataUtil.removeSystemData(competitorEntity.getData());
                Object richTextData = removeRichText(competitorEntity.getData());
                competitorModel.insert(competitorEntity);
                dataId = competitorEntity.getId();
                // 设置属性用于返回
                setPartialAttributes(dataId, competitorEntity.getSubFormData(), competitorEntity.getData(), competitorEntity.getAddTime(),
                        competitorEntity.getUpdateTime(), paasFormDataEntity, beforeSaveVO);

                //文件柜数据保存
                saveFile(formDataAddDTO, paasFormDataEntity, userVO);
                //富文本数据保存
                saveRichText(formDataAddDTO, paasFormDataEntity, richTextData);
            }
            return new SaveVO(noApprovalRequired, paasFormDataEntity, dataId, userVO);
        } catch (XbbException e) {
            log.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            log.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public void saveRollBack(Long dataId, String corpid, Integer saasMark, Integer businessType) throws XbbException {

    }

    @Override
    public FormDataAddVO afterSave(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        Long dataId = saveVO.getDataId();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            if (Objects.equals(1, saveVO.getNoApprovalRequired())) {
                SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
                BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);

                packageSaasFormInsertSaveDTO(saasFormSaveDTO, paasFormDataEntity);
                saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(beforeSaveVO.getSaasNeedRedundantAttrPojo());
                competitorService.afterSave(saasFormSaveDTO);
                // dynamic
                saveDynamic(saasFormSaveDTO);
                // log
                afterSaveLog(formDataAddDTO, paasFormEntity, paasFormDataEntity, saveVO, beforeSaveVO);
                //关联动态添加
                dynamicHelp.addLinkData(saasFormSaveDTO);
                // 业务规则
                activeRule(formDataAddDTO, beforeSaveVO, paasFormDataEntity, beforeSaveVO.getPaasFormEntityExt());
                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
                formDataAddVO.setDataId(saveVO.getDataId());
                formDataAddVO.setFormDataId(saveVO.getDataId());
            } else {
                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
            }
            return formDataAddVO;
        }  catch (XbbException e) {
            log.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            log.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    /**
     * 新建竞争对手添加动态
     * @param saasFormSaveDTO
     */
    private void saveDynamic(SaasFormSaveDTO saasFormSaveDTO){

        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getDataId();
        Long formId = newPaasFormDataEntity.getFormId();
        String corpid = newPaasFormDataEntity.getCorpid();
        String creatorId = newPaasFormDataEntity.getCreatorId();

        //竞争对手创建日志添加
        Runnable runnable = () -> {
            try {
                //获取用户信息
                UserEntity userEntity = userModel.getByKey(creatorId, corpid);

                DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategyByBusinessType(XbbRefTypeEnum.COMPETITOR.getCode());
                DynamicSaveDTO dynamicSaveDTO = DynamicSaveDTO.initDynamicSaveDTO(dataId, formId, saasFormSaveDTO, userEntity, null);
                dynamicStrategy.save(dynamicSaveDTO);
            }catch (Exception e){
                log.error("竞争对手日志创建失败，失败原因：",e);
            }
        };

        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
    }

    @Override
    public SaveVO saveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            UserVO userVO = getUserName(formDataAddDTO, paasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();
            Object richTextData = removeRichText(paasFormDataEntity.getData());
            CompetitorEntity competitorEntity = new CompetitorEntity();
            JSONObject originData = (JSONObject) paasFormDataEntity.getData().clone();
            BeanUtil.copyProperties(paasFormDataEntity, competitorEntity);
            FormDataUtil.removeSystemData(competitorEntity.getData());
            competitorModel.insert(competitorEntity);
            dataId = competitorEntity.getId();
            // 设置属性用于返回
            setPartialAttributes(dataId, competitorEntity.getSubFormData(), competitorEntity.getData(), competitorEntity.getAddTime(), competitorEntity.getUpdateTime(), paasFormDataEntity, beforeSaveVO);

            //文件柜数据保存
//            saveFile(formDataAddDTO, paasFormDataEntity, userVO);
            //富文本数据保存
            saveRichText(formDataAddDTO, paasFormDataEntity, richTextData);
            paasFormDataEntity.setData(originData);
            return new SaveVO(noApprovalRequired, paasFormDataEntity, dataId, userVO);
        } catch (XbbException e) {
            log.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            log.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public FormDataAddVO afterSaveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        Long dataId = saveVO.getDataId();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
            BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);

            packageSaasFormInsertSaveDTO(saasFormSaveDTO, paasFormDataEntity);
            saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(beforeSaveVO.getSaasNeedRedundantAttrPojo());
            competitorService.afterSaveForWorkflow(saasFormSaveDTO);

            formDataAddVO.setDataId(saveVO.getDataId());
            formDataAddVO.setFormDataId(saveVO.getDataId());
            formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
            formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
            return formDataAddVO;
        }  catch (XbbException e) {
            log.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            log.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }
}
